#ifndef JIAJIA_JJFRONT_HPP
#define JIAJIA_JJFRONT_HPP

#include"jiajiastd.hpp"

#include"jjenv.hpp"
#include"ir.hpp"

#include"lmccencode.hpp"
#include"lmccstack.hpp"

namespace jiajia{

    class jjfront{
    private:
        my::ufile mFile;
        my::ubuffer mBuf;
        token mToken;

        jjenv mEnv;
        jjmid & mMid;
    public:
        jjfront(jjmid & m):
            mBuf(),
            mToken(),
            mEnv(),
            mMid(m)
        {}

        // 向前一个 unicode
        my::unicode nextUnicode(){
            return my::unicode::ToHalf(mBuf.nextUnicode(mFile));
        }

        // 回退一个 unicode
        void backUnicode(){
            mBuf.backUnicode();
        }

        word_t nextWord(){
            word_t w;
            w = lmcc::NEXTWORD(*this);
            while(token::IsIgnore(w)){
                mBuf.throwOnly();
                w = lmcc::NEXTWORD(*this);
            }

            mToken.init(mBuf, w);
            switch(w){
            case lmcc::_assgin:
                if(!mEnv.lhsFlag()) return lmcc::_eq;
                return lmcc::_assgin;
            default:
                if(w < lmcc::begin_of_err){
                    std::cerr<<"jiajia::jjfront::nextWord 发生错误了。但是我却还没有写错误处理的函数。哈哈哈"<<std::endl;
                    w = lmcc::_empty;
                }
                break;
            }

            return w;
        }

        void genAssignHead(){
            // 弹出 =
            s.pop();

            mEnv.enterASSIGN(s.topExpr().begin, s.topExpr().result);
            mEnv.toRHS();
            s.pop();
        }

        // 一些编辑，生成代码的操作
        bool genExpr(const code_t code, const word_t w){
            // 2020-3-19 为了减少临时值的创建个数，打算返回值将由后面的表达式填充
            // 比如　a = -1, $ 为 未知的意思
            // -1 将生成节点　[code::MINUS, $, 1, $]
            // 返回值部分由　a　节点填充。
            // [code::MINUS, $, 1, a]
            // 唯一的不好的地方是，如果某条语句无返回值呢？
            // 有多条语句要回填返回值呢？

            // 2020-3-19 我放弃了，还是多几个临时值好，生成简单

            lmcc::reducestack & s = reducestack::en();
            token t;
            irnode * node = mMid.ir().insertBack(mEnv.topEnd());
            // 关于 begin
            // 1. 如果 rhs 是一个表达式，那么 begin 会被 rhs.begin 覆盖
            // 2. 如果 lhs 是一个表达式，那么 begin 会被 lhs.begin 覆盖

            irnode * begin = node;
            irnode * end = nullptr;
            value_t * rhs = nullptr;
            value_t * lhs = nullptr;
            value_t * result = nullptr;

            switch(code){
            case code::ASSIGN:{
                // lhs = rhs

                // rhs
                lmcc::rsnode & rhs_node = s.top();

                if(rhs_expr.begin != nullptr)
                    begin = rhs_expr.begin;

                rhs = rhs_expr.result;
                s.pop();

                // 弹出 assign
                t = std::move(s.topToken());
                s.pop();

                // lhs
                lmcc::rsnode & lhs_node = s.top();
                if(s.topWord() == lmcc::_idexpr){
                    begin = lhs_expr.begin;
                    // 如果是 _idexpr 则要进行左值转换即，code::FIND -> code::INSERT, code::GFIND -> code::GINSERT
                    irnode::ToLHExpr(lhs_expr.begin, lhs_expr.end);
                }
                s.pop();

                node = genUnary(code::ASSIGN, rhs, lhs);
                node->set(-1, t);
            }
                break;
            case code::MINUS:{
                // _sub rhs

                // rhs
                lmcc::rsnode & rhs_node = s.top();
                if(rhs_node.begin != nullptr)
                    begin = rhs_node.begin;

                rhs = rhs_node.result;
                s.pop();

                // 弹出 _sub
                t = std::move(s.topToken());
                s.pop();

                result = mMid.tab().newTemp();
                node->genUnary(code::MINUS, rhs, result);
                node->set(-1, t);
            }
                break;
            case code::ADD:
            case code::SUB:
            case code::MULT:
            case code::DEV:
            case code::LINK:
            case code::EQ:
            case code::NE:
            case code::GT:
            case code::LT:
            case code::GE:
            case code::LE:{
                // lhs code::XXX rhs

                // 弹出右边的值
                lmcc::rsnode & rhs_node = s.topExpr();
                rhs = rhs_node.result;
                if(rhs_node.begin != nullptr) begin = rhs_node.begin;
                s.pop();

                // 弹出运算符
                t = std::move(s.topToken());
                s.pop();

                // 弹出左边的值
                lmcc::rsnode & lhs_node = s.topExpr();
                lhs = lhs_node.result;
                if(lhs_node.begin != nullptr) begin = lhs_node.begin;
                s.pop();

                result = mMid.tab().newTemp();
                node->genEXPR(code, lhs, rhs, result);
                node->set(-1, t);
            }
                break;
            default: break;
            }
            s.pushExpr(w, std::move(t), begin, node, result);
            return true;
        }

        // 逻辑运算
        inline void genAND(const word_t word){
            genLogic(code::IFTRUE, word);
        }

        inline void genOR(const word_t word){
            genLogic(code::IFFALSE, word);
        }

        void genLogic(const code_t code, const word_t word){
            lmcc::reducestack & s = reducestack::en();
            irnode * if_node = nullptr;
            irnode * node1 = nullptr;
            irnode * node2 = nullptr;
            irnode * begin = nullptr;
            irnode * end = mMid.ir().insertBack(mEnv.topEnd());
            end->genGOTONEXT();

            value_t * result = mMid.tab().newTemp();
            // lhs && rhs 的逻辑如下
            // 如果 lhs == true, 返回 rhs
            // 如果 lhs == false, 返回 lhs
            // 所以转换成 IR 如下
            // 0. TOBOOL lhs result
            // 1. IFTRUE result m
            //  ...
            // n. TOBOOl rhs result
            // m. ...

            // lhs || rhs 的逻辑如下
            // 如果 lhs == true, 返回 lhs
            // 如果 lhs == false, 返回 rhs
            // 所以转换成 IR 如下
            // 0. TOBOOL lhs result
            // 1. IFFALSE result n
            //  ...
            // n. TOBOOL rhs result
            // m. ...

            // 弹出右边的值
            lmcc::rsnode rhs_node = std::move(s.top());
            value_t * rhs = rhs_node.result;
            s.pop();

            // 弹出 && ，||
            token t = std::move(s.topToken());
            s.pop();

            lmcc::rsnode lhs_node = std::move(s.topExpr());
            value_t * lhs = lhs_node.result;
            s.pop();

            // 1. 首先 lhs 必须要在 rhs 前面运算。
            // 2. 因为有可能 lhs 为常量或其他只有值的 rsnode ，所以有可能会造成 rhs 永远先比 lhs 作出运算
            // 3. 也有可能两个都是只有值，那就可以随意添加，没有运算先后

            // 4. 两个都是只有值的生成时，按循序生成
            // node1    :   [TOBOOL, lhs, result]
            // if_node  :   [IFXXX, result, n]
            // node2    :   [TOBOOL, rhs, result]
            // n        :   ...

            // 5. 当 lhs 为只有值时，
            // 把 node1 生成在 rhs_node.begin 前
            // 把 if_node 生成在 rhs_node.begin 前
            // 把 node2 生成在 rhs_node.end 后
            // node1            :   [TOBOOL, lhs, result]
            // if_node          :   [IFXXX, result, n]
            // rhs_node.begin   :   ...
            // rhs_node.end     :   ...
            // node2            :   [TOBOOL, rhs, result]
            // n                :   ...

            // 6. 当 rhs 为只有值时，
            // 把 node1 生成在 lhs_node.end 后
            // 把 if_node 生成在 node1 后
            // 把 node2 生成在 if_node 后
            // lhs_node.begin   :   ...
            // lhs_node.end     :   ...
            // node1            :   [TOBOOL, lhs, result]
            // if_node          :   [IFXXX, result, n]
            // node2            :   [TOBOOL, rhs, result]
            // n                :   ...

            // 7. 当 lhs 和 rhs 都有值时
            // 把 node1 生成在 rhs_node.begin 前
            // 把 node2 生成在 rhs_node.begin 前
            // 把 if_node 生成在 rhs_node.begin 前
            // lhs_node.begin   :   ...
            // lhs_node.end     :   ...
            // node1            :   [TOBOOL, lhs, result]
            // if_node          :   [IFXXX, result, n]
            // rhs_node.begin   :   ...
            // rhs_node.end     :   ...
            // node2            :   [TOBOOL, rhs, result]
            // n                :   ...

            jjir & ir = mMid.ir();
            if(rhs_node.begin == nullptr){

                node1 = ir.insertBack(end);
                if_node = ir.insertBack(end);
                node2 = ir.insertBack(end);

                begin = (lhs_node.begin != nullptr)? lhs_node.begin:node1;
            }else{
                node1 = ir.insertBack(rhs_node.begin);
                if_node = ir.insertBack(rhs_node.begin);
                node2 = ir.insertNext(rhs_node.end);

                begin = node1;
            }

            node1->genUnary(code::TOBOOl, lhs, lhs_node.result);
            node1->set(-1, lhs_node.token);

            if_node->genIF(code, result, end);

            node2->genUnary(code::TOBOOl, rhs, rhs_node.result);
            node2->set(-1, rhs_node.token);

            s.pushExpr(word, std::move(t), begin, node2, result);
        }

        // _id
        void genID(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            token & t = s.topToken();
            string_t * name = mMid.insertID(std::move(t.text));
            value_t * table_val = nullptr;

            value_t * result = mMid.newTemp();
            irnode * node = mMid.ir().insertBack(mEnv.end());

            jjenvnode & e = mEnv.findSEQ();
            if(s.mode == jjenvnode::INIT_MODE){
                table_val = mEnv.mainValue();
                // 如果没有主值，或进入了右值生成节奏则使用全局变量查找
                if(table_val == nullptr || !mEnv.lhsFlag()){
                    node->genGLOBAL(code::GFIND, name, result);
                    node->set(-1, t);
                }else{
                    node->genTABLE(code::FIND, table_val, name, result);
                    node->set(-1, t);
                }
            }else{
                table_val = e.node(jjenvnode::SEQ_TA);
                node->genTABLE(code::FIND, table_val, name, result);
                node->set(-1, t);
            }
            s.top.set(lmcc::_idexpr, node, node, result);
        }

        // _ta
        bool genTA(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            value_t * main_val = nullptr;
            jjenvnode & e = mEnv.findSEQ();
            if(e.mode == jjenvnode::INIT_MODE){
                main_val = mEnv.mainValue();
                if(main_val == nullptr){
                    // 没有主值的报错
                    return false;
                }
            }else{
                main_val = e.value(jjenvnode::SEQ_TA);
            }
            s.top().set(lmcc::_ta, main_val);
            return true;
        }

        // idexpr _de _id
        void genIDEXPR(){
            lmcc::reducestack & s = lmcc::reducestack::en();

            value_t * val = nullptr;
            value_t * result = nullptr;

            irnode * node = mMid.ir().insertBack(mEnv.end());
            irnode * begin = node;

            jjsymtab & tab = mMid.tab();
            // 抛出 _id
            string_t * name = tab.insertID(std::move(s.topToken().text));
            s.pop();

            // 抛出 ‘的’
            token t = std::move(s.topToken());
            s.pop();

            val = s.top().result;
            if(s.topWord() == lmcc::_ta){
                result = tab.newTemp();
            }else{
                begin = s.top().begin;
                result = val;
            }
            s.pop();

            node->genTABLE(code::FIND, val, name, result);
            node->set(-1, t);
            s.pushExpr(lmcc::_idexpr, std::move(t), begin, node, val);
        }

        // idexpr _lbracket expr _rbracket
        void genATEXPR(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            value_t * lhs = nullptr;
            value_t * rhs = nullptr;
            value_t * result = nullptr;
            irnode * node = mMid.ir().insertBack(mEnv.end());
            irnode * begin = node;
            // 抛出 _rbracket
            s.pop();

            // 抛出 expr
            rhs = s.topExpr().result;
            if(s.topExpr().begin != nullptr) begin = s.topExpr().begin;
            s.pop();

            // 抛出 _lbracket
            token t = std::move(s.topToken());
            s.pop();

            lhs = s.top().result;
            if(s.topWord() == lmcc::_ta){
                result = mMid.tab().newTemp();
            }else{
                begin = s.top().begin;
                result = lhs;
            }
            s.pop();

            node->genExpr(code::AT, lhs, rhs, result);
            s.pushExpr(lmcc::_idexpr, std::move(t), begin, node, result);
        }

        // 生成常量
        void genConstant(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            lmcc::rsnode & rs = s.top();
            value_t * val = mMid.tab().newTemp();
            rs.token.parseValue(val);
            rs.set(lmcc::_constant, val);
        }

        // (expr) -> expr
        void genParenFactor(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            // 弹出 )
            s.pop();

            lmcc::rsnode node(std::move(s.top()));
            s.pop();

            // 弹出 (
            s.pop();

            s.push_back(std::move(node));
        }

        // 生成判断语句
        // 因为 IF 都在环境中保存着，所以干脆直接输入弹出多少个算了
        void genIF(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            s.pop();
            s.pop();

            s.pushStmt(lmcc::_stmt, mEnv.topBegin(), mEnv.topEnd()->mBack);
            mEnv.quit();
            mEnv.toLHS();
        }

        void genIFHead(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            value_t * result = nullptr;
            // 弹出 expr
            result = s.topResult();
            s.pop();

            // 弹出 _if
            token t = std::move(s.topToken());
            s.pop();

            mEnv.enterIF(t, mMid.ir(), result);
            s.pushWord(lmcc::_ifhead);
        }

        bool genELSE(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            s.pop();

            if(mEnv.topMode() == irnode::ELSE_MODE){

                return false;
            }

            mEnv.enterELSE(mMid.ir());
            mEnv.toLHS();
            s.pushWord(lmcc::_stmt);
            return true
        }

        bool genELIF(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            value_t * result = s.topExpr().result;
            s.pop();

            // 弹出 _elif
            token t = std::move(s.topToken());
            s.pop();

            if(mEnv.topMode() == irnode::ELSE_MODE){

                return false;
            }

            mEnv.enterELIF(t, mMid.ir(), result);
            mEnv.toLHS();
            s.pushWord(lmcc::_stmt);
            return true;
        }

        // 生成循环语句
        void genLoopHead(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            // 弹出 _comma
            s.pop();
            // 弹出 _loop
            token t = std::move(s.topToken());
            s.pop();

            mEnv.enterLOOP(t, mMid.tab(), mMid.ir());
            mEnv.toLHS();
            s.pushWord(lmcc::_loophead);
        }

        // 因为 LOOP 都在环境中保存着，所以干脆直接输入弹出多少个算了
        void genLoop(){
            // 循环语句比较特殊
            // 默认应该是一个死循环，然后一个跳出的条件判断
            // 还有一个循环因子记录已经第几次循环，所以需要在循环开始之前初始化为 0
            // 所以循环语句的大概模样为:
            // 0 : [code::assgin, 0, factor]
            // 1 : [code::add, factor, 1, factor]
            // ...
            // n : [code::IFFALSE, cond, 1 ]
            // n+1 : ...

            // 如果忽略了直到语句，则完全为死循环，大概模样为:
            // 0 : [code::assgin, 0, factor]
            // 1 : [code::add, factor, 1, factor]
            // ...
            // n : [code::goto, 1]
            // n+1 : ...

            // 循环语句块没有返回值，谨记，使用 STMT_FLAG 记录

            lmcc::reducestack & s = lmcc::reducestack::en();
            s.pop();
            s.pop();

            s.pushStmt(lmcc::_stmt, mEnv.topBegin(), mEnv.topEnd()->mBack);
            mEnv.quit();
            mEnv.toLHS();
        }

        bool genLoopBodys(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            // 弹出 loopbody
            s.pop();

            // 弹出 _comma
            token t = std::move(s.topToken());
            s.pop();

            // 弹出 loopbodys
            s.pop();
            if(mEnv.topMode() == irnode::UNITIL_MODE){

                return false;
            }

            mEnv.toLHS();
            s.pushWord(lmcc::_stmt);
            return true;
        }

        bool genUntil(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            value_t * result = s.topExpr().result;
            s.pop();

            // 弹出 _until
            token t = std::move(s.topToken());
            s.pop();

            if(mEnv.topMode() != jjenvnode::LOOP_MODE){
                
                return false;
            }

            mEnv.enterUNTIL(t, result);
            s.pushWord(lmcc::_stmt);
            return true;
        }

        bool genLoopFactor(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            jjenvnode & e = mEnv.findLOOP();
            // 找到循环语句
            if(e.mode == jjenvnode::LOOP_MODE){
                value_t * factor = e.value(jjenvnode::LOOP_FACTOR);
                s.pushResult(lmcc::_loopfactor, factor);
            }else{
                // 没有进入循环，循环因子，使用错误报错
                return false;
            }
            return true;
        }

        // 函数
        // 生成函数头部
        bool genCallHead(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            token t = std::move(s.topToken());
            func_t f = func::Find(t.text);
            if(f == nullptr){
                // 函数找不到报错
                return false;
            }
            s.pop();

            // 弹出 @
            s.pop();

            mEnv.enterCALL(mMid.tab(), mMid.ir(), f);
            mEnv.toRHS();
            s.pushToken(lmcc::_callhead, std::move(t));
            return true;
        }

        // 函数调用
        void genCall(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            jjenvnode & e = mEnv.top();
            value_t * result = e.value(jjenvnode::CALL_RESULT);
            irnode * node = mMid.insertBack(mEnv.topEnd());


            // 弹出 argsstmt 
            s.pop();

            // 弹出 函数名
            token t = std::move(s.topToken());
            s.pop();

            node->genCall(e.func(jjenvnode::CALL_FUNC), result);
            node->set(-1, t);

            mEnv.quit();
            mEnv.toRHS();
            s.pushExpr(lmcc::_call, std::move(t), e.begin(), node, result);
        }

        // 生成第一个参数
        bool genArg(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            irnode * node = mMid.insertBack(mEnv.end());
            irnode * begin = node;

            // 弹出 expr
            s.pop();

            node->genARGPUSH(s.topExpr().result);
            s.pushWord(lmcc::_args);
            return true;
        }

        // 生成第 n 个参数
        bool genArgs(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            irnode * node = mMid.insertBack(mEnv.end());

            // 弹出 expr
            s.pop();

            // 弹出 _comma
            s.pop();

            // 弹出 _args
            s.pop();

            node->genARGPUSH(s.topExpr().result);
            s.pushWord(lmcc::_args);
            return true;
        }

        // 以主语作为参数
        void genArgMainValue(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            irnode * node = nullptr;
            value_t * main_val = nullptr;
            jjenvnode & e = mEnv.findSEQ();
            if(e.mode == INIT_MODE){
                main_val = mEnv.mainValue();
            }else{
                main_val = e.node(jjenvnode::SEQ_TA);
            }

            if(main_val != nullptr){
                node = mMid.insertBack(mEnv.end());
                node->genARGPUSH(main_val);
            }

            s.pushWord(lmcc::_stmt);
        }

        // 数组初始化操作
        // 【
        bool genSeqHead(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            value_t * main_val = nullptr;
            jjenvnode & e = mEnv.findSEQ();
            if(e.mode == INIT_MODE){
                main_val = mEnv.mainValue();
                if(main_val == nullptr){

                    return false;
                }
            }else{
                main_val = e.node(jjenvnode::SEQ_MAIN);
            }
            mEnv.enter(mMid.tab(), mMid.ir(), main_val);
            s.pop();
            return true;
        }

        // 、
        void genSeqDun(){
            mEnvStack.enterPUSH(mMid.ir());
            mEnv.toLHS();
        }

        // 】
        void genSeqTail(){
            s.pop();
            mEnv.quit();
        }

        void genSeqStmt(){
            s.top().set(lmcc::_stmt);
        }

        // 语句块的一些生成 stmt
        void genExprStmt(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            lmcc::rsnodey & node = s.top();
            word_t w = s.topWord();
            jjenvnode & e = mEnv.findSEQ();
            if(e.mode == jjenvnode::INIT_MODE){
                if(mEnv.mainValue() == nullptr && s == lmcc::_idexpr){
                    irnode::ToLHS(node.begin, node.end);
                    mEnv.setMainValue(s.topExpr().result);
                }
            }else{
                // 如果是数组初始化阶段，则需要解释一些特殊的
                // {1+2、@xxx、 "abc"}: 右值表达式，相当于 {他 = 1+2、 他 = @xxx、 他 = "abc"}
                // {年龄 = 18、他}: 赋值表达式和他表达式，相当于 {他的年龄=18、他}
                if(w != lmcc::_assginexpr || w != lmcc::_ta){
                    irnode * node = mMid.ir().insertBack(mEnv.topEnd());
                    node->genUnary(code::ASSIGN, node.result, e.value(jjenvnode::SEQ_TA));
                    node->set(-1, node.token);
                }
            }
            s.top().set(lmcc::_stmt);
        }

        // 循环停止语句
        bool genBreakStmt(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            jjenvnode & e = mEnv.findLOOP();
            if(e.mode != jjenvnode::LOOP_MODE){
                // 没有进入循环但使用，循环停止，的报错
                return false;
            }

            irnode  * node = mMid.ir().insertBack(mEnv.topEnd());
            node->genGOTO(e.topEnd());
            node->set(-1, s.topToken());
            s.top().set(lmcc::_stmt, node, node);
            return true;
        }

        // 循环返回语句
        bool genContinueStmt(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            jjenvnode & e = mEnv.findLOOP();
            if(e.mode != jjenvnode::LOOP_MODE){
                // 没有进入循环但使用，循环停止，的报错
                return false;
            }

            irnode  * node = mMid.ir().insertBack(mEnv.topEnd());
            node->genGOTO(e.node(jjenvnode::LOOP_FMOVE));
            node->set(-1, s.topToken());
            s.top().set(lmcc::_stmt, node, node);
            return true;
        }

        // 通用
        void genStmts(const int len){
            lmcc::reducestack & s = lmcc::reducestack::en();
            irnode * begin = nullptr;
            irnode * end = nullptr;
            for(int i = 0; i < len; ++i){
                if(end == nullptr)
                    end = s.top().end;
                if(s.top().begin != nullptr)
                    begin = s.top().begin;
                s.pop();
            }

            s.pushStmt(lmcc::_stmts, begin, end);
            mEnv.toLHS();
        }

        // 语句块
        void genBlock(const int len){
            lmcc::reducestack & s = lmcc::reducestack::en();
            irnode * begin = nullptr;
            irnode * end = nullptr;
            for(int i = 0; i < len; ++i){
                if(end == nullptr)
                    end = s.top().end;
                if(s.top().begin != nullptr)
                    begin = s.top().begin;
                s.pop();
            }

            mEnv.toLHS();
            mEnv.setMainValue(nullptr);
            s.pushWord(lmcc::_block, begin, end);
        }

        // 一些生成代码那里使用的代码
        inline void shi(){
            lmcc::reducestack & s = lmcc::reducestack::en();
            switch(mToken.word){
            case lmcc::_true:
            case lmcc::_false:
            case lmcc::_num:
            case lmcc::_str:
            case lmcc::_realnum:
            case lmcc::_add:
            case lmcc::_sub:
            case lmcc::_mult:
            case lmcc::_dev:
            case lmcc::_assgin:
            case lmcc::_lt:
            case lmcc::_gt:
            case lmcc::_le:
            case lmcc::_ge:
            case lmcc::_ne:
            case lmcc::_if:
            case lmcc::_elif:
            case lmcc::_until:
            case lmcc::_at:
                mEnv.toRHS();
                s.pushToken(std::move(mToken));
                break;
            default:
                s.pushToken(std::move(mToken));
                break;
            }
        }
    };
}

#endif
